package video.background.Controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.AES;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import video.background.Controller.ControllerParams.LoginParams;
import video.background.Controller.ControllerParams.ResetPasswordParams;
import video.background.Controller.ControllerParams.SignInParams;
import video.background.Dao.UserDao;
import video.background.Model.Users;
import video.background.Services.EmailServices;
import video.background.Utils.*;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.alibaba.fastjson.JSON;
import java.util.*;
import com.aliyuncs.dysmsapi.model.v20170525.*;
import video.background.Utils.Random;

import javax.mail.MessagingException;
import java.time.*;
import java.util.Map;

/**
 * @program: background
 * @description:
 * @author: hlt
 * @create: 2023-08-07 17:26
 **/
@RestController
@RequestMapping("/verify")
@CrossOrigin(origins = "*", maxAge = 3600)
@Api(tags = "用户登录前的相关接口")
public class VerifyController {

    private static final String maleAvatar = "https://smart-box-1311261154.cos.ap-nanjing.myqcloud.com/voices/male.png";


    @Autowired
    private UserDao userDao;

    @Autowired
    private EmailServices emailServices;

    @ApiOperation("测试")
    @GetMapping("/getTest")
//    @ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "Long", paramType = "path")
    public String test(){
        return "Get测试成功！";
    }

    @ApiOperation("向用户的邮箱发送重置密码的验证码")
    @GetMapping("/sendMessageForFindPassword")
    public Result sendMessageForFindPassword(@RequestParam String email) throws Exception {
        LambdaQueryWrapper<Users> ulqw = new LambdaQueryWrapper<>();
        ulqw.eq(Users::getEmail,AESUtils.encrypt(email));
        Users users = userDao.selectOne(ulqw);
        if(users == null) return Result.Error("未查询到用户信息", null);
//        if(users.isEmailVerify() == false)
//            return Result.Error("用户邮箱未验证，不能发送验证码！", null);
        String verifyCode = Random.generateString(6);
        String currentTime = DateTimeUtils.dateTimeAndSecondToString();
        users.setVerifyCodeTime(currentTime);
        users.setVerifyCode(verifyCode);
        userDao.update(users, ulqw);
        users.setEmail(email);
        emailServices.sendMailForFindPassword(users, verifyCode);
        return Result.Success("验证码已发送，5分钟内有效！", null);
    }

    @PostMapping("/resetPassword")
    @ApiOperation("重置密码")
    public Result resetPassword(@RequestBody ResetPasswordParams data) throws Exception {
        String verifyCode = data.getVerifyCode();  //前端传来的验证码
        String email = data.getEmail();
        String password = data.getPassword();
//        System.out.println("email: " + email);
        LambdaQueryWrapper<Users> ulqw = new LambdaQueryWrapper<>();
        ulqw.eq(Users::getEmail,AESUtils.encrypt(email));
//        System.out.println("email密文：" + AESUtils.encrypt(email));
        Users users = userDao.selectOne(ulqw);
        if(users == null) return Result.Error("您的邮箱不对哦！！！！", null);
        // 检查验证码是否正确
        users.setEmail(email);
        Result result = Verify.VerifyCheck(users,verifyCode);
        if(result.getMsg().equals("验证码正确有效")) {
            users.setPassword(AESUtils.encrypt(password));
            users.setEmail(AESUtils.encrypt(email));
            userDao.updateById(users);
            MessageUtils.sendMessage(users.getUserId(), users.getUserName(),5,null);
            return Result.Success("重置成功",null);
        }
        return result;
    }

    @GetMapping("/verifyEmailBeforeSignIn")
    @ApiOperation("注册前先验证邮箱是否有效的接口")
    public Result verifyEmailBeforeSignIn(@RequestParam String email) throws Exception {
//        System.out.println("验证邮箱时的email: " + email);
        LambdaQueryWrapper<Users> ulqw = new LambdaQueryWrapper<>();
        // 判断邮箱是否相同(判断和密文的相同)
        ulqw.eq(Users::getEmail, AESUtils.encrypt(email));
        Users users = userDao.selectOne(ulqw);
        if(users != null){
            /**
             * 3种情况：
             *   1、邮箱已经被注册了，password和username等信息齐全；
             *   2、是临时注册，password还没有，但是邮箱验证码已过期，可以继续写入
             *   3、是临时注册，password还没有，邮箱验证码还未过期，属请求过于频繁
             * */
//            System.out.println("Users不为空，不能插入");
            if(users.getPassword() != null) return Result.Error("您的邮箱已经被人用了哦~",null);
            else if(DateTimeUtils.getTimeBetween(users.getVerifyCodeTime()) < 60)
                return Result.Error("您的请求过于频繁，请稍后再试！",null);
        }
        // users == null 数据库中目前还没有这条数据
        // 判断邮箱格式
        if(!EmailJudge.emailJudge(email)) return Result.Error("邮箱格式不正确", null);
        // 向邮箱发送验证码
        String verifyCode = Random.generateString(6);
        String username = Random.generateString(8);
        String currentTime = DateTimeUtils.dateTimeAndSecondToString();
        if (users == null){
//            System.out.println("email密文：" + Encrypt.numEncrypt(email));
            Users users1 = new Users(null, username, '1', null, AESUtils.encrypt(email), null,
                    null, DateTimeUtils.dateTimeToString(), maleAvatar, true, verifyCode, currentTime,5);
            userDao.insert(users1);
//            System.out.println("数据库已插入临时数据！");
        } else{
            users.setVerifyCode(verifyCode);
            users.setVerifyCodeTime(currentTime);
            userDao.updateById(users);
//            System.out.println("数据库临时数据已更新！");
        }
        Users users2 = userDao.selectOne(ulqw);
        String text = AESUtils.decrypt(users2.getEmail());
        users2.setEmail(text);
//        System.out.println("验证的邮箱：" + text);
        emailServices.sendMailForVerify(users2, verifyCode);
        return Result.Success("验证码已发送至您的邮箱，5分钟内有效！", null);
    }

    @PostMapping("/signIn")
    @ApiOperation("用户注册的接口")
    public Result signIn(@RequestBody SignInParams data) throws Exception {
        String email = data.getEmail();
        String password = data.getPassword();
        String verifyCode = data.getVerifyCode();
        if (email.equals("") || password.equals("") || verifyCode.equals(""))
            return Result.Error("数据不全", null);
        LambdaQueryWrapper<Users> ulqw = new LambdaQueryWrapper<>();
        ulqw.eq(Users::getEmail, AESUtils.encrypt(email));  //加密
        Users users = userDao.selectOne(ulqw);
        if(users == null) return Result.Error("请核对您的邮箱！", null);
        if(!users.getVerifyCode().equals(verifyCode)){
            userDao.delete(ulqw); // 将注册的临时信息删除
            return Result.Error("验证码不正确！请稍后尝试",null);
        }else if(DateTimeUtils.getTimeBetween(users.getVerifyCodeTime()) > 300){  // 验证码5分钟有效
            userDao.delete(ulqw); // 将注册的临时信息删除
            return Result.Error("验证码已过期，请重试！",null);
        }else{
            users.setEmailVerify(true);
            users.setPassword(AESUtils.encrypt(password));  //加密
            userDao.update(users, ulqw);
        }
        return Result.Success("注册成功！", null);
    }

    // @RequestBody LoginParams data
    @PostMapping("/login")
    @ApiOperation("登录接口")
    public Result login(@RequestBody LoginParams data) throws Exception {
        String email = data.getEmail();
        String password = data.getPassword();
        if (email.equals("") || password.equals(""))
            return Result.Error("数据不全", null);
        LambdaQueryWrapper<Users> ulqw = new LambdaQueryWrapper<>();
        ulqw.eq(Users::getEmail, AESUtils.encrypt(email));
        Users users1 = userDao.selectOne(ulqw);
        if (users1 == null) return Result.Error("用户未注册！", null);
        if(users1.getPassword().equals(AESUtils.encrypt(password))){
            String token = JwtUtils.createToken(users1);
            return Result.Success("登录成功！", token);
        }
        return Result.Error("密码错误", null);
    }

    @PostMapping("/testSMS")
    @ApiOperation("测试短信服务")
    public Result testSMS(@RequestBody Map<String, String>data){
        String s = data.get("phone");

        DefaultProfile profile = com.aliyuncs.profile.DefaultProfile.getProfile("cn-hangzhou", "LTAI5tK6ksuJBw2DQUzkLwvv", "9j6jt9tYOfaMGiz4E3ale3x5veSk6A");
        IAcsClient client = new com.aliyuncs.DefaultAcsClient(profile);

        System.out.println(s);

        // 创建API请求并设置参数
        SendSmsRequest request = new SendSmsRequest();

        request.setPhoneNumbers(s);

        request.setSignName("高性能声纹识别平台");
        request.setTemplateCode("SMS_462740372");
        String param = "{\"code\":\"123456\"}";
        request.setTemplateParam(param);

        try {
            SendSmsResponse response = client.getAcsResponse(request);
            System.out.println(JSON.toJSONString(response));
            System.out.println(response.getRequestId());
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            // 打印错误码
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }


        return Result.Success("请求成功", null);
    }


}
